package sdk.org.apache.lucene.D01_Hello;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Paths;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.IndexableFieldType;
import org.apache.lucene.queries.function.valuesource.DualFloatFunction;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.SimpleFSDirectory;

public class Indexer {
    // 写索引
    private IndexWriter indexWriter;

    /**
     * 实例化写索引
     * 
     * @param dir
     *            保存索引的目录
     * @throws IOException
     */
    public Indexer(String dir) throws IOException {
        Directory indexDir = new SimpleFSDirectory(Paths.get(dir));

        /**
         * IndexWriterConfig实例化该类的时候如果是空的构造方法，那么默认 public IndexWriterConfig() { this(new
         * StandardAnalyzer()); }
         */
        
        Analyzer analyzer=new StandardAnalyzer();  //分词器
        IndexWriterConfig conf = new IndexWriterConfig(analyzer);

        indexWriter = new IndexWriter(indexDir, conf);
    }

    /**
     * 索引文件
     */

    public void index(File file) throws Exception {
        System.out.println("被索引的文件为：" + file.getCanonicalPath());
        Document document = getDocument(file);
        indexWriter.addDocument(document);

    }

    /**
     * 从文件中获取文档
     * 
     * @param file
     * @return
     * @throws IOException
     */
    private Document getDocument(File file) throws IOException {
        Document document = new Document();

        Field contentField = new TextField("fileContents", new FileReader(file));
        /**
         * Field.Store.YES表示把该Field的值存放到索引文件中，提高效率，一般用于文件的标题和路径等常用且小内容小的。
         */
        Field fileNameField = new TextField("fileName", file.getName(), Field.Store.YES);
        Field filePathField = new TextField("filePath", file.getCanonicalPath(), Field.Store.YES);

        document.add(contentField);
        document.add(fileNameField);
        document.add(filePathField);

        return document;
    }

    /**
     * 创建索引
     * 
     * @param dataFile 数据文件所在的目录
     * @return 索引文件的数量
     * @throws Exception
     */
    public int CreateIndex(String dataFile, FileFilter filter) throws Exception {
        File[] files = new File(dataFile).listFiles();
        for (File file : files) {
            /**
             * 被索引文件必须不能是 1.目录 2.隐藏  3. 不可读 4.不是txt文件，
             * 否则不被索引
             */
            if (!file.isDirectory() && !file.isHidden() && file.canRead() && filter.accept(file)) {
                index(file);
            }
        }
        return indexWriter.numRamDocs();
    }

    /**
     * 关闭写索引
     * 
     * @throws IOException
     */
    public void close() throws IOException {
        indexWriter.close();

    }

    /**
     * 测试
     * @param args
     */
    public static void main(String[] args) {
        String indexDir="E:\\Temp\\lucene\\index";
        String dataDir="E:\\Temp\\lucene\\data";
        int indexFileCount=0;
        Indexer indexer=null;
        try {
            indexer=new Indexer(indexDir);
            long startTime=System.currentTimeMillis();
            indexFileCount=indexer.CreateIndex(dataDir, new FileFilter());
            long endTime=System.currentTimeMillis();
            System.out.println("索引文件共花费："+(endTime-startTime)+" 毫秒");
            System.out.println("一共索引了"+indexFileCount+"个文件");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                indexer.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        
    }

}
